﻿using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace Leuphana.GuidedTour.App
{
    public class NavigationService
    {
        #region Singleton

        private static NavigationService instance;
        public static NavigationService Current
        {
            get
            {
                if (instance == null)
                {
                    instance = new NavigationService();
                }

                return instance;
            }
        }

        #endregion

        private Dictionary<string, string> pageTypeMappings;

        protected NavigationService()
        {
            pageTypeMappings = new Dictionary<string, string>();
        }

        /// <summary>
        /// Register a new page type.
        /// </summary>
        /// <param name="type">Page type identifier.</param>
        /// <param name="uri">Page navigation uri.</param>
        public void RegisterPageType(string type, string uri)
        {
            if (pageTypeMappings.ContainsKey(type))
                throw new ArgumentException("type is already registered");

            pageTypeMappings.Add(type, uri);
        }

        /// <summary>
        /// Navigate to a page.
        /// </summary>
        /// <remarks>
        /// Utilizes current apps root visual.
        /// App has to be initialized and root visual has to be a phone application frame.
        /// </remarks>
        /// <param name="pageType"></param>
        /// <param name="query"></param>
        public void Navigate(string pageType, string query = null)
        {
            string uri;

            // Retrieve the page type.
            if (!pageTypeMappings.TryGetValue(pageType, out uri))
                throw new ArgumentException("unknown page type");

            // Add the query to the uri.
            if (!String.IsNullOrEmpty(query))
            {
                uri += (uri.Contains('?') ? "&" : "?") + query;
            }

            // Magic happens here.
            var frame = App.Current.RootVisual as PhoneApplicationFrame;

            if (frame == null)
                throw new InvalidOperationException("App.RootVisual is not initialized of not of type PhoneApplicationFrame.");

            frame.Navigate(new Uri(uri, UriKind.Relative));
        }
    }

    public class NavigationCommand : ICommand
    {
        private string pageType;
        private string parameterName;

        public NavigationCommand(string pageType, string parameterName = null)
        {
            this.pageType = pageType;

            if (parameterName != null)
            {
                this.parameterName = parameterName;
            }

            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            if (parameterName != null && parameter != null)
            {
                NavigationService.Current.Navigate(pageType, parameterName + "=" + parameter.ToString());
            }
            else
            {
                NavigationService.Current.Navigate(pageType);
            }
        }
    }
}
